#ifndef GB28181_SERVICE_H
#define GB28181_SERVICE_H

#include "gb28181_interface.h"
#include "stream/gb28181_invite.h"
#include "business/gb28181_ptz.h"
#include "business/gb28181_record.h"
#include <string>
#include <memory>
#include <vector>
#include <thread>
#include <atomic>
#include <functional>
#include <mutex>
#include <condition_variable>
#include <unordered_map>
#include <nlohmann/json.hpp>

extern "C" {
#include <eXosip2/eXosip.h>
#include <osipparser2/osip_message.h>
}

namespace El {
namespace GB28181 {

struct SipServerConfig {
    bool enabled;
    std::string device_id;
    std::string server_id;
    std::string server_ip;
    int server_port;
    int local_port;
    std::string password;
    std::string domain;
    int heartbeat_interval;
    int register_interval;
    int register_expires;
    int max_timeout_count;
    int channel_count;
    std::string civil_code;
    struct ChannelConfig {
        std::string id;
        std::string name;
    };
    std::vector<ChannelConfig> channel_configs;
    std::vector<std::string> channels;
};

class GB28181Service {
public:
    GB28181Service();
    ~GB28181Service();

    // 新的初始化接口，接受JSON配置和服务索引
    bool Initialize(const nlohmann::json &config, int service_index);
    bool Start();
    void Stop();
    bool IsRunning() const;

    // 获取服务索引
    int GetServiceIndex() const
    {
        return service_index_;
    }

    DeviceStatus GetDeviceStatus() const;

    // Media session management
    using MediaSessionCallback = std::function<void(const MediaSession &session, bool started)>;
    void SetMediaSessionCallback(MediaSessionCallback callback)
    {
        media_session_callback_ = callback;
    }

    // PTZ control management
    using PTZControlCallback = std::function<bool(const PTZControlInfo &info)>;
    void SetPTZControlCallback(PTZControlCallback callback)
    {
        ptz_control_callback_ = callback;
    }

    // Record query management
    using RecordQueryCallback = std::function<std::vector<RecordInfo>(const RecordQueryInfo &query)>;
    void SetRecordQueryCallback(RecordQueryCallback callback)
    {
        record_query_callback_ = callback;
    }

private:
    friend class GB28181Register;

    struct ServerContext {
        SipServerConfig config;
        eXosip_t *exosip_context;
        int registration_id;
        DeviceStatus status;
        std::chrono::steady_clock::time_point last_heartbeat;
        std::chrono::steady_clock::time_point last_register;
        std::mutex mutex;

        // Authentication info
        std::string realm;
        std::string nonce;
        std::string opaque;
        std::string algorithm;
        bool auth_required;
        int auth_retry_count;

        ServerContext()
            : exosip_context(nullptr),
              registration_id(-1),
              status(DeviceStatus::OFFLINE),
              auth_required(false),
              auth_retry_count(0)
        {
        }
    };

    bool InitializeServer();
    void ShutdownServer();

    void ProcessMessageLoop();
    void ProcessEvent(eXosip_event_t *event);

    void HeartbeatTimer();
    void RegisterTimer();

    void UpdateDeviceStatus(DeviceStatus status, const std::string &message = "");
    const char *GetStatusString(DeviceStatus status) const;

    // 验证配置
    bool ValidateConfig(const nlohmann::json &config);

    // Media session handling
    void OnMediaSession(const MediaSession &session, bool started);

    void SendRegisterRequest(bool use_auth);
    bool ShouldRefreshRegister() const;

    SipServerConfig config_;
    std::unique_ptr<ServerContext> server_;
    int service_index_;

    std::atomic<bool> running_;
    std::thread message_thread_;
    std::thread heartbeat_thread_;
    std::thread register_thread_;

    // Media session management
    MediaSessionCallback media_session_callback_;
    std::unordered_map<std::string, MediaSession> active_sessions_;
    std::mutex sessions_mutex_;

    // PTZ control management
    PTZControlCallback ptz_control_callback_;

    // Record query management
    RecordQueryCallback record_query_callback_;

    static constexpr int HEARTBEAT_TIMEOUT_SECONDS = 180;
    static constexpr int REGISTER_TIMEOUT_SECONDS = 60;
    static constexpr int MAX_RETRY_COUNT = 3;
};

} // namespace GB28181
} // namespace El

#endif // GB28181_SERVICE_H
